<template>
  <!-- 30ms保证流畅并兼容性能 -->
  <Container v-resize:throttle.30="onResize" :min-width="containerMinWidth">
    <Column v-for="(column,index) in columns" :key="index">
      <Item
        v-for="(data, index) in column"
        :key="`column_${index}`"
        :data-uuid="data.uuid"
        :data="data"
        :types="types"
        @click.native="handleClick(data.data)">
      </Item>
    </Column>
    <!-- lines -->
    <LeaderLine
      v-for="(item, index) in coordinates"
      :key="`coord_${index}`"
      :start="item.start"
      :end="item.end"/>
  </Container>
</template>

<script>
// plugins
import resize from 'vue-resize-directive'
// layout
import Container from '../components/Container'
import Column from '../components/Column'
// components
import Item from '../components/Item'
import LeaderLine from '../components/LeaderLine'
// utils
import transfer from '../utils/transfer'
import coordinate from '../utils/element'

export default {
  name: 'lineage-impact',
  directives: {
    resize,
  },
  components: {
    Container,
    Column,
    LeaderLine,
    Item
  },
  props: {
    source: Object,
    types: Array,
    upstream: {
      type: String,
      default: 'upstream'
    },
    downstream: {
      type: String,
      default: 'downstream'
    }
  },
  data () {
    return {
      columns: [],
      lines: [],
      coordinates: []
    }
  },
  computed: {
    containerMinWidth () {
      let minWidth = 900
      if (this.columns.length) {
        minWidth = this.columns.length * 320
      }
      return minWidth
    }
  },
  watch: {
    source: {
      handler (data) {
        if (data) {
          const result = transfer(data, {
            upstream: this.upstream,
            downstream: this.downstream
          })
          this.columns = result.columns
          this.lines = result.lines
          // 赋值后下一帧执行渲染线方法
          this.$nextTick(() => {
            this.render()
          })
        }
      },
      immediate: true,
      deep: true
    }
  },
  methods: {
    render () {
      const result = this.lines.map(item => {
        return coordinate(getNode(item.start), getNode(item.end))
      })
      this.coordinates = result
    },
    handleClick (item) {
      this.$emit('click', item)
    },
    onResize () {
      this.render()
    }
  }
}

function getNode (id) {
  return document.querySelector(`[data-uuid="${id}"]`)
}
</script>
